<?php
/**
 * Interface for Zend_Db_Tree_nested adapters. 
 * 
 * @category   Zend
 * @package    Zend_Db
 * @author     Steshenko Alexander (http://lcf.name)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
interface Zend_Db_Tree_Nested_Adapter_Interface
{
    /**
     * Constructor.
     *
     * Supported params for $config are:
     * - db              = user-supplied instance of database connector,
     * - tableName       = table name.
     * - columns         = table columns
     * - aliases         = aliases for return-type queries
     * - relativeKey     = node id column in relative table
     * - treeId          = tree id
     * - relativeTableName   = relative table name
     *
     * @param  mixed $config Array of user-specified config options
     * @return void
     */
    public function __construct($config = array());
    
    /**
     * Sets tree id
     *
     * @param integer $treeId
     */
    public function setTreeId($treeId);
    
    /**
     * Sets name of relative table
     *
     * @param string $relativeTableName
     */
    public function setRelativeTableName($relativeTableName);
    
    /**
     * Return aliases for columns
     *
     * @return array
     */
    public function getAliases();
    
    /**
     * Set aliases for columns
     *
     * @param array $aliases
     */
    public function setAliases($aliases);
    
    /**
     * Zend_Db_Select to row array convertation
     *
     * @param Zend_Db_Select $select
     * @return array
     */
    public function fetchRow(Zend_Db_Select $select);
    
    /**
     * Zend_Db_Select to array convertation
     *
     * @param Zend_Db_Select $select
     * @return array
     */
    public function fetchAll(Zend_Db_Select $select);
    
    /**
     * Begin transaction method
     * 
     * You can use table lock for data bases
     * without transaction
     *
     */
    public function beginTransaction();
    
    /**
     * Commit transaction method
     * 
     * You can use table lock for data bases
     * without transaction
     *
     */
    public function commitTransaction();
    
    /**
     * Calculate free tree id in structure table
     *
     * @return integer
     */
    public function getFreeTreeId();
    
    /**
     * Get node information
     *
     * @param int $nodeId node id
     * @return Zend_Db_Select
     */
    public function getNode($nodeId);

    /**
     * Get node information by its left key
     *
     * @param int $leftKey node's left key
     * @return Zend_Db_Select
     */
    public function getNodeByLeftKey($leftKey);

    /**
     * Get node information by its right key
     *
     * @param int $rightKey node's right key
     * @return Zend_Db_Select
     */
    public function getNodeByRightKey($rightKey);
    
    /**
     * Get value of minimal left key in the tree.
     * Actually it should always be equal 1
     *
     * @return int 
     */
    public function getMinLeftKey();
    
    /**
     * Get maximal right key in the tree
     *
     * @return int
     */
    public function getMaxRightKey();
    
    /**
     * Insert node.
     *
     * @param int $leftKey left key
     * @param int $rightKey right key
     * @param int $level level
     * @return int new node id
     */
    public function insertNode($leftKey, $rightKey, $level);
    
    /**
     * Update tree for node insertion
     * 
     * If its adjacent insert, $adjacent param has be true,
     * if its insert of the child, $adjacent param has to be false 
     * 
     * @param int $key right or left key (depends on place of insertion)
     * @param boolean $adjacent adjacent / child insertion
     */
    public function createUpdate($key, $adjacent = false);

    
    /**
     * One of the validation methods
     * Left key of the node is always lower than right key
     *
     * @return boolean
     */
    public function validateLeftRightKeys();
    
    /**
     * One of the validation methods
     * a) The lowest left key is always equal 1
     * b) The biggest right key is always equal number of nodes * 2
     *
     * @return boolean
     */
    public function validateMaxMinKeys();
    
    /**
     * One of the validation methods:
     * a) difference between right and left key are always odd
     * b) If level of the node is odd then the left key are always even 
     * 		(and same for even levels)
     *
     * @return boolean
     */
    public function validateKeysDiff();
    
    /**
     * One of the validation methods:
     * Keys are always uniq (independent is it left or right)
     * 
     * @return boolean
     */
    public function validateUniqKeys();
    
    /**
     * Delete node and all children by left and right keys
     *
     * @param int $leftKey
     * @param int $righKey 
     */
    public function delete($leftKey, $rightKey);
    
    /**
     * Delete data from relative table
     * 
     * @param array $ids array with deleted nodes id
     * @return boolean
     */
    public function deleteCallback($ids);
    
    /**
     * Update tree after deletion
     *
     * @param int $leftKey left key deleted node
     * @param int $righKey right key deleted node
     */
    public function deleteUpdate($leftKey, $rightKey);
    
    /**
     * Delete tree
     *
     * @return boolean
     */
    public function deleteTree();
    
    /**
     * Get whole tree
     *
     * @return Zend_Db_Select
     */
    public function getTree();
    
    /**
	 * Get path to node
     *
     * @param int $leftKey left key
     * @param int $rightKey right key
     * @return Zend_Db_Select
     */
    public function getPath($leftKey, $rightKey);

    /**
     * Get open tree.
     * Open tree is all root nodes, path to the node and children of the node.
     *
     * @param int $leftKey left key
     * @param int $rightKey right key
     * @param int $level node level
     * @return Zend_Db_Select
     */
    public function getOpenTree($leftKey, $rightKey, $level);
    
    /**
     * Get parent node's information
     *
     * @param int $leftKey
     * @param int $rightKey
     * @param int $level
     * @return Zend_Db_Select
     */
    public function getParent($leftKey, $rightKey, $level);
    
    /**
     * Get root nodes (with level = 1)
     *
     * @return Zend_Db_Select
     */
    public function getRootNodes();

    /**
     * Get children of the node. 
     * Note, that not all descendant will be selected, but only
     * children - descendant with level = parent level + 1
     *
     * @param int $leftKey
     * @param int $rightKey
     * @param int $level
     * @return Zend_Db_Select
     */
    public function getChildren($leftKey, $rightKey, $level);
    
    /**
     * Get all descendants of the node and the node itself (branch)
     *
     * @param int $leftKey
     * @param int $rightKey 
     * @return Zend_Db_Select
     */
    public function getBranch($leftKey, $rightKey);
    
    /**
     * Get all descendants of the node
     *
     * @param int $leftKey
     * @param int $rightKey 
     * @return Zend_Db_Select
     */
    public function getDescendants($leftKey, $rightKey);
    
    /**
     * Move node up on the tree
     *
     * @param int $leftKey moved node left key
     * @param int $rightKey moved node right key
     * @param int $skewTree keys' offset
     * @param int $skewLevel level's offset
     * @param int $near "point of movement"
     * @return boolean
     */
    public function moveNodeUp($leftKey, $rightKey, $skewTree, $skewLevel, $near);
    
    /**
     * Move node down on the tree
     *
     * @param int $leftKey moved node left key
     * @param int $rightKey moved node right key
     * @param int $skewTree keys' offset
     * @param int $skewLevel level's offset
     * @param int $near "point of movement"
     * @return boolean
     */
    public function moveNodeDown($leftKey, $rightKey, $skewTree, $skewLevel, $near);
    
    /**
     * Returns columns for external joining
     *
     * @return string
     */
    public function getIdColumn();
    
    /**
     * Returns relative key column for external joining
     *
     * @return string
     */
    public function getRelativeKeyColumn();
}